package control

import (
	"lesson01/instructions/base"
	"lesson01/rtda"
)

// Return 没有返回
type Return struct {
	base.NoOperandsInstruction
}

func (e *Return) Execute(frame *rtda.Frame) {
	frame.Thread().PopFrame()
}

// AReturn 返回引用
type AReturn struct {
	base.NoOperandsInstruction
}

func (e *AReturn) Execute(frame *rtda.Frame) {
	thread := frame.Thread()
	currentFrame := thread.PopFrame()
	invokerFrame := thread.TopFrame()
	val := currentFrame.OperandStack().PopRef()
	invokerFrame.OperandStack().PushRef(val)
}

// IReturn 返回int
type IReturn struct {
	base.NoOperandsInstruction
}

func (e *IReturn) Execute(frame *rtda.Frame) {
	thread := frame.Thread()
	currentFrame := thread.PopFrame()
	invokeFrame := thread.TopFrame()
	val := currentFrame.OperandStack().PopInt()
	invokeFrame.OperandStack().PushInt(val)

}

// LReturn 返回long
type LReturn struct {
	base.NoOperandsInstruction
}

func (e *LReturn) Execute(frame *rtda.Frame) {
	thread := frame.Thread()
	currentFrame := thread.PopFrame()
	invokeFrame := thread.TopFrame()
	val := currentFrame.OperandStack().PopLong()
	invokeFrame.OperandStack().PushLong(val)
}

// FReturn 返回float
type FReturn struct {
	base.NoOperandsInstruction
}

func (e *FReturn) Execute(frame *rtda.Frame) {
	thread := frame.Thread()
	currentFrame := thread.PopFrame()
	invokeFrame := thread.TopFrame()
	val := currentFrame.OperandStack().PopFloat()
	invokeFrame.OperandStack().PushFloat(val)
}

// DReturn 返回double
type DReturn struct {
	base.NoOperandsInstruction
}

func (e *DReturn) Execute(frame *rtda.Frame) {
	thread := frame.Thread()
	currentFrame := thread.PopFrame()
	invokeFrame := thread.TopFrame()
	val := currentFrame.OperandStack().PopDouble()
	invokeFrame.OperandStack().PushDouble(val)
}
